package service

import (
	"hanyun-admin/src/entity"
	"hanyun-admin/src/utils"
	"log"
	"sort"
	"strconv"
	"time"
)

//获取所有的菜单
func SelectMenuTreeAll()(menu []entity.Menu){
	//初始化一个数组切面
	menu = make([]entity.Menu,0)
	//由于orm框架使用的是xorm  本人用的不是很熟练 所以这个地方改用原生sql语句
	sql := "select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.visible, ifnull(m.perms,'') as perms, m.is_frame, m.menu_type, m.icon, m.order_num, m.create_time " +
		"from sys_menu m where m.menu_type in ('M', 'C') and m.visible = 0 " +
		"order by m.parent_id, m.order_num"
	gres,err := DbEngine.Query(sql)
	//处理异常
	if err != nil{
		panic(err)
	}
	for _,v := range gres{
		var m entity.Menu
		//这种读取方式直接读取成map[string]interface{}类型，时间有限 自行百度！！！
		//把从map中解析值转成string，然后在转int64，int64类似于Java中long类型
		menuId,_ := strconv.ParseInt(string(v["menu_id"]),10,64)
		m.MenuId=menuId
		m.MenuName=string(v["menu_name"])
		parentId,_ := strconv.ParseInt(string(v["parent_id"]),10,64)
		m.ParentId = parentId
		orderNum,_ := strconv.Atoi(string(v["order_num"]))
		m.OrderNum=orderNum
		m.Path=string(v["path"])
		m.Component=string(v["component"])
		m.IsFrame=string(v["is_frame"])
		m.MenuType=string(v["menu_type"])
		m.Visible=string(v["visible"])
		m.Perms=string(v["perms"])
		m.Icon=string(v["icon"])
		m.CreateBy=string(v["icon"])
		//2006-01-02 15:04:05 此写法为固定写法 我也不知道原因是啥  反正golang的开发者就是这么定义的！！骚年按着这个来吧
		//fmt.Println(string(v["create_time"]))
		createTime,_ := time.Parse("2006-01-02 15:04:05", string(v["create_time"]))
		m.CreateTime=createTime
		m.UpdateBy=string(v["update_by"])
		updateTime,_ := time.Parse("2006-01-02 15:04:05",string(v["update_time"]))
		m.UpdateTime=updateTime
		m.Remark=string(v["remark"])

		//给上面我们定义好的数组切面中add数据 你可以把它当成一个list去理解 append方法可以理解成list.add()
		menu = append(menu,m)
	}
	return
}
//获取所有得父节点
func GetChildPerms(menu []entity.Menu,parentId int64)(m []entity.Menu){
	//此数组存储得是parentId为0得数据
	//m = make([]entity.Menu,0)
	for _,x := range menu{
		//注意！x就代表当前的list，跟Java的迭代器next()方法一样
		if x.ParentId==parentId{
			//把当前元素追加进上面定义好的切面对象数组  声明一下  golang中没有对象 所以我是用Java的思想来写golang
			//recursionFn(menu,x)
			m = append(m,x)
		}
	}
	return
}

//获取菜单数据权限
func GetMenuPermission(user entity.User)(arr []string){
	arr = make([]string,0)
	if user.IsAdmin() {
		arr = append(arr,"*:*:*")
	}else {

	}
	return
}

func BuildData(list []entity.Menu)map[int64]map[int64]entity.Menu{
	var data map[int64]map[int64]entity.Menu = make(map[int64]map[int64]entity.Menu)
	for _,v := range list{
		id := v.MenuId
		fid := v.ParentId
		if _,ok := data[fid]; !ok{
			data[fid] = make(map[int64]entity.Menu)
		}
		data[fid][id]=v
	}
	return data
}

func MakeTreeCore(index int64,data map[int64]map[int64]entity.Menu)[]entity.Menu{
	tmp := make([]entity.Menu,0)
	for id,item := range data[index]{
		if data[id] != nil {
			item.Children = MakeTreeCore(id,data)
		}
		tmp = append(tmp,item)
	}
	return tmp
}

//菜单排序
func ArraySort(menu []entity.Menu)  {
	sort.Slice(menu, func(i, j int) bool {
		if menu[i].OrderNum < menu[j].OrderNum {
			return true
		}
		return false
	})
	for _,v := range menu{
		if v.Children != nil {
			ArraySort(v.Children)
		}
	}
}
//获取路由地址
func GetRouterPath(menu entity.Menu)string{
	routerPath := menu.Path
	//非外连接并且是一级目录
	if menu.ParentId==0 && "1"==menu.IsFrame{
		routerPath = "/" + menu.Path
	}
	return routerPath
}
func GetComponent(menu entity.Menu)string{
	var str string
	if menu.Component=="" {
		str = "Layout"
	}else {
		str = menu.Component
	}
	return str
}
//构建前端路由所需要的菜单
func BuildMenus(menu []entity.Menu)[]entity.RouterVo{
	routers := make([]entity.RouterVo,0)
	for _,v := range menu{
		router := entity.RouterVo{
			Name:       utils.Capitalize(v.Path),
			Path:       GetRouterPath(v),
			Component:  GetComponent(v),
			Meta:     entity.MetaVo{
				Title:v.MenuName,
				Icon:v.Icon,
			},
		}
		if len(v.Children)>0 && v.Children!=nil && "M"== v.MenuType{
			router.AlwaysShow=true
			router.Redirect = "noRedirect"
			router.Children=BuildMenus(v.Children)
		}
		routers = append(routers,router)
	}
	return routers
}
//获取菜单列表
func SelectMenuList(menu entity.Menu)[]entity.Menu  {
	menuList := make([]entity.Menu,0)
	sql := DbEngine.Select("*")
	if menu.MenuName != "" {
		sql.Where("menu_name like ?","%"+menu.MenuName+"%")
	}
	if menu.Visible != "" {
		sql.Where("visible = ?",menu.Visible)
	}
	err := sql.Find(&menuList)
	if err != nil {
		log.Println("select menu list error ",err)
	}
	return menuList
}
//新增菜单
func InsertSysMenuData(menu entity.Menu)error{
	_,err := DbEngine.Insert(menu)
	return err
}
//菜单详情
func SelectSysMenuByMenuId(menuId int64)entity.Menu  {
	var menu entity.Menu
	_,err := DbEngine.Id(menuId).Get(&menu)
	if err != nil {
		log.Println("select sysMenu by menuId error ",err)
	}
	return menu
}
//更新数据
func UpdateSysMenuData(menu entity.Menu)error{
	_,err := DbEngine.Id(menu.MenuId).Update(menu)
	return err
}
//删除
func DeleteSysMenuByMenuId(menuId int64)error{
	_,err := DbEngine.Id(menuId).Delete(entity.Menu{})
	return err
}